/*
 * DrawPage.cpp
 *
 *  Created on: 2010-10-25
 *      Author: wenjian
 */

#include "DrawPage.h"
#include "Layer.h"
#include "Element.h"
#include "ImageLayerMerger.h"
#include "DefaultCursor.h"
#include "../draw/MouseEvent.h"

namespace Ed {

  ULONG_PTR DrawPage::gpToken;

  DrawPage::DrawPage(HWND hWnd, real x, real y, real width, real heigth)
    :graphics(NULL), imageLayerMerger(this), layerMerger(NULL){
    setGeometry(x, y, width, heigth);
    init(hWnd);
  }

  DrawPage::~DrawPage() {
    if(graphics)delete graphics;
  }

  void inline DrawPage::init(HWND hWnd){
    // 取 DC
    hostDC = GetDC(hWnd);

    // 创建双缓冲
    bufferDC = CreateCompatibleDC( hostDC );
    HBITMAP bmp = CreateCompatibleBitmap( hostDC, (int)width(), (int)height());
    SelectObject( bufferDC, bmp );
    DeleteObject( bmp );

    //生成 GDI+ Graphics
    graphics = new Gdiplus::Graphics(bufferDC);
    graphics->SetPageUnit(Gdiplus::UnitPixel);
    graphics->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
    graphics->SetTextRenderingHint(Gdiplus::TextRenderingHintClearTypeGridFit);
    graphics->Clear(Gdiplus::Color(0,0,0));
  }

  /**
   * 画所有图层, 将从最低层图层开始绘制
   */
  void DrawPage::draw(Gdiplus::Graphics* g) {
    if(!isModified()){
      return;
    }
    long stime = clock();
    g->Clear(Gdiplus::Color(0,0,0));
    getLayerMerger()->merge();
    //清除绘图页被修改状态
    setModified(false);
  }

  void DrawPage::refresh(bool flag){
    // 拷贝缓冲区内容到画布
    if(flag){
      draw(graphics);
    }
    BitBlt(hostDC, (int)x(), (int)y(), (int)width(), (int)height(), bufferDC, 0, 0, SRCCOPY);
  }

  void DrawPage::trackMouseEvent(EventType type, int x, int y, unsigned int buttons, void* source){
    MouseEvent mousevent(type, x, y, buttons, source?source:this);
    trackEvent(&mousevent);
    refresh(true);
  }

  /**
   * 跟踪鼠标事件
   */
  void inline DrawPage::trackMouseEvent(EventType type, int x, int y, unsigned int buttons, const KeySequence& ks,  void* source){
    MouseEvent mousevent(type, x, y, buttons, ks, source?source:this);
    trackEvent(&mousevent);
    refresh(true);
  }

  bool DrawPage::refreshCursor(){
    Layer* layer = (Layer*)getMouseHoveringLayer();
    if(layer){
      Element* e = (Element*)layer->getMouseHoveringElement();
      DefaultCursor* c = NULL;
      if(e){
        c = (DefaultCursor*)e->getCursor();
      }
      if(!c){
        c = (DefaultCursor*)layer->getCursor();
      }
      if(c && c->getStyle()){
        SetCursor(c->getStyle());
        return true;
      }
    }
    return false;
  }

  void DrawPage::setLayerMerger(LayerMerger* lm){
    if(layerMerger != lm){
      layerMerger = lm;
      //重画所有元素
      for(Layers::iterator it = layers.begin(); it != layers.end(); it++){
        Layer* l = (Layer*)(*it);
        l->setRedrawAll();
        l->setModified(true);
      }
    }
  }

}
